import random
import time
import logging
from concurrent.futures import ProcessPoolExecutor, as_completed
from datetime import datetime
import pandas as pd


# 核心处理函数，模拟耗时操作并随机返回内容
def process_text(input_text):
    """
    接收一段文字，随机返回一段文字，耗时2秒
    """
    time.sleep(2)
    candidates = ["返回内容A", "返回内容B", "返回内容C", "返回内容D", "返回内容E"]
    return random.choice(candidates)


# 读取Excel文件中的ID和测试文本
def read_texts_from_excel(file_path):
    """
    从Excel文件读取ID和测试文本，假设第一行为表头，第一列为ID，第二列为测试文本
    返回 [(id, text), ...] 的列表
    """
    df = pd.read_excel(file_path)
    return list(zip(df["ID"], df["测试文本"]))


# 并行测试主流程，包含QPS控制和日志记录
def run_parallel_test(input_id_texts):
    qps = 10  # 每秒最大并发请求数
    results = []  # 用于保存所有请求的结果

    # 配置日志，输出到文件和控制台
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s [%(levelname)s] %(message)s",
        handlers=[
            logging.StreamHandler(),
            logging.FileHandler("parallel_test.log", encoding="utf-8"),
        ],
    )

    # 创建进程池，最大并发数为qps
    with ProcessPoolExecutor(max_workers=qps) as executor:
        futures = {}
        for id_, text in input_id_texts:
            send_time = datetime.now()
            logging.info(f"请求ID {id_} | 发送时间: {send_time} | 输入内容: {text}")
            futures[executor.submit(process_text, text)] = (id_, text, send_time)

        # 等待所有任务完成，记录返回时间和结果
        for future in as_completed(futures):
            id_, text, send_time = futures[future]
            result = future.result()
            return_time = datetime.now()
            log_msg = (
                f"请求ID {id_} | 返回时间: {return_time} | 输入内容: {text} | "
                f"返回内容: {result}"
            )
            logging.info(log_msg)
            # 保存结果，包括ID、输入、输出、发送和返回时间
            results.append((id_, text, result, send_time, return_time))

    return results


# 主程序入口，读取Excel并启动并行测试
if __name__ == "__main__":
    excel_path = r"C:\Users\JP\Desktop\测试文本1.xlsx"  # 请替换为你的Excel文件路径
    input_id_texts = read_texts_from_excel(excel_path)
    run_parallel_test(input_id_texts)
